home *** CD-ROM | disk | FTP | other *** search
-
-
-
- SALT.DOC Copyright (C) 1990 Liberation Enterprises.
- An introduction to Telix's script language.
-
-
- This is not a comprehensive SALT tutor, and if you are seeking such you
- won't find it here (a more extensive tutor will most likely be released
- in the future). If you understand the logon scripts provided with
- Telix, then you will probably be wasting your time reading this. This
- document was designed for beginners, and simply explains some basics of
- SALT, and some easy-to-use but useful functions. Everything is
- explained in simple terms, to enable non-programmers or new Telix users
- to write usable scripts. You will also be shown how to make use of the
- dreaded SALT manual.
-
- Learning SALT is usually the only major obstacle people run into with
- Telix. As I'm sure you are aware, SALT is one of, if not *the* most
- powerful 'script' language available for any communications program.
- Unfortunately, extra power usually translates into a more involved
- learning process--the more power (or features) you have, the more there
- is to learn. However, you need not learn the entire language and study
- the entire SALT manual to create useful scripts. There are a few SALT
- statements and functions listed below, that will enable you to automate
- fairly complex tasks, without getting into any major programming. The
- functions are:
-
- capture(); Open, close, or pause a capture file. Specify the name
- of the capture file between double quotes (e.g.
- capture("TELIX.CAP"). If you don't specify a path,
- Telix creates the file in the same directory as
- TELIX.EXE. See CAPCMD.SLT for example usage of
- capture().
- cputs(); Put a 'string' of text out the communications port
- (cputs is 'c' for communications port (modem), 'put'
- for... put, 's' for string. A string is just a bunch of
- characters grouped together between double quotes; a
- sentence (e.g. "This is a string").
- delay_scr(); Pause the script from running for a certain amount of
- time. This is similar to delay(), but it allows the
- screen to be updated with incoming characters for the
- duration of the delay. Delays can be used to wait for a
- prompt, etc.
- dos(); Gives you access to DOS from within a Telix script.
- 'Access to DOS' means you can carry out a simple DOS
- command, such as COPY, DEL, etc., or you can even run
- another program if necessary. The command must be
- placed between double quotes. Examples:
- dos("DEL TEST.FIL"); ...or... dos("123.EXE");
- goto <label> A script or program normally runs from top to bottom, or
- from the first statement to the last. To change this,
- and skip immediately to another section of the script,
- you use 'goto's.
- hangup(); Breaks the connection by hanging up.
- return(); End the current 'function' right where we are, and
- return to the 'caller'. The 'caller' depends on where
- the return() is found. If you return() from the main()
- function that all scripts start at, then you return to
- the calling script (The Liberator, etc.) or to Telix
-
-
- The L i b e r a t o r v2.31 SALT.DOC - Page 2
-
-
-
- terminal mode. The Liberator tests any value you
- return() from your script's main() function.
- waitfor(); Wait for some text to come in from the BBS, or until a
- specified number of seconds elapses. Combined with
- cputs(), this is a very useful function and can automate
- many tasks.
-
- Two other useful functions are:
-
- send(); Send a file to the BBS (upload)
- receive(); Receive a file from the BBS (download)
-
- You can write many useful scripts using just these functions. However,
- your scripts wouldn't be capable of making any intelligent decisions
- using just the above... For example, waitfor() allows you to wait for a
- specified number of seconds for a certain message or prompt to come in
- from the BBS; but what if the message doesn't come in? You don't want
- to answer a question if the question hasn't even been asked, so you
- must have some way to test whether the text came in or not. This is
- where these two statements come into play:
-
- if() Tests whether something is TRUE (successful) or FALSE
- (unsuccessful).
- while() Does something 'while' a certain condition is TRUE.
-
- What's all this about TRUE and FALSE? How do these things 'test'
- whether something is successful (TRUE) or unsuccessful (FALSE)? There
- is just a simple rule that they follow, which says that: "TRUE is
- anything that is not zero". The number 1 is TRUE, since it is not
- zero, the letter 'A' must be TRUE since it is not zero... 1 + 1 (one
- plus one) is TRUE, since it's end result is not zero, etc. "FALSE is
- anything that does end up to be zero"... 0 itself is FALSE, 1 - 1 (one
- minus one) is FALSE since its end result is zero.
-
- This doesn't have to make sense... (and it certainly didn't for me at
- first) that's just the way it is. Anything that results in a zero
- value is considered FALSE, anything that results in a non-zero value is
- considered TRUE. If something is FALSE, it is also known as unsuccess-
- ful, or 'not' successful. 'Not' is used in SALT to refer to something
- that is not TRUE: if it's "not TRUE", it must be FALSE, or zero. I'm
- attempting to burn this into your memory since it is used all over the
- place in SALT and is important to pick up. The true/false rule makes
- scripts 'smart' enough to carry out meaningful decisions. Almost
- everything in SALT evaluates to TRUE or FALSE and can be tested with
- if() and while(). Just using TRUE and FALSE was enough to create The
- Liberator, and many of the other programs you use.
-
- If I had some money, how much do I have? I have TRUE amount of money
- (it must be TRUE since it isn't zero...). To test the value in SALT, I
- could use:
-
- if (money)
-
-
-
- The L i b e r a t o r v2.31 SALT.DOC - Page 3
-
-
-
- ...which is the same as saying "if money is TRUE"... Of course, it
- wouldn't do much good just to know this unless I was going to do
- something with the information, like this:
-
- if (money)
- spend();
-
- This is how if() operates. 'If' whatever is between the brackets ends
- up to be TRUE (not zero), then the next statement (up to the first ;)
- is carried out: spend(); in this case. Then we move happily along (by
- the way, scripts execute from top to bottom, unless told otherwise).
- If whatever is between if()'s brackets evaluates to FALSE ('money'
- would be FALSE if it was equal to zero) then the statement immediately
- following the if() is *skipped*. [Don't try to compile these ex-
- amples... they're just nonsense used for demonstration. Some usable
- examples are given later.]
-
- if (this_is_TRUE)
- then_do_this();
-
- The next line following an if() or while() is normally indented to show
- that it may not get executed if the result is FALSE, and depends on the
- if(). [Note that the SALT compiler doesn't care whether you indent or
- not... in fact you could place an entire SALT script all on one line an
- it will compile just fine. Indending, and placing statements on
- different lines is done solely for the benefit of people who read the
- script. It makes scripts easier to follow and debug.]
-
- Note also that the if() is not followed by a semicolon. This is
- because if() executes the next statement UP TO the first semicolon. If
- you use if(); then the semicolon is found immediately, and the if is
- useless. The SALT script compiler (CS.EXE) gives a warning if you
- specify if(); or while(); like this, with no statement to execute
- before the semicolon.
-
- While() works in the same way as if(), but instead of only executing
- the next statement once, then moving along, it keeps running it over
- and over again until whatever is between the brackets ends up to be
- FALSE (or until we hit a 'break;' statement... which 'breaks' out of
- while() 'loops'). Since it runs the next statement more than once,
- while() is said to cause a 'loop' (you needn't remember this... it's
- just a programming term). For example, just spend()ing ONCE is no fun
- while() we still have some money left, so:
-
- while (money) // while money is TRUE, or non-zero
- spend(); // spend() some, then go back and check
- // again in the while()
- // once the while() is FALSE, (when money is equal to zero), then
- // we exit the 'loop' and continue with any following statements
-
- You could also reverse this by using the word 'not'. This would be an
- appropriate while() loop to execute after the above spend()ing spree:
-
-
-
- The L i b e r a t o r v2.31 SALT.DOC - Page 4
-
-
-
- while (not money) // while money is 'not' TRUE (not TRUE is 0...FALSE)
- work(); // go to work, then check again
-
- Now, I suppose you're wondering where all this is leading to...
- Believe it or not, if you understand the above it's only a matter of
- time until you can write your own Liberator. There isn't much more to
- The Liberator than 'if this, do that, else do this'... 'while this, do
- that', etc. This is how all programs work. Everything must be
- planned for and tested with statements like if() and while(). Since
- computers basically have the intelligence of lightbulbs... making a
- program appear 'smart' is a lot of work, and may require hundreds of
- if/while's--each testing a different condition which you must an-
- ticipate ahead of time. If you don't anticipate something, and if that
- something happens, the computer will not automatically handle it for
- you. Computers know absolutely nothing about what task is actually
- going on, and basically shouldn't be considered as 'intelligent' any
- more than your toaster would be (okay... they're a *little* smarter
- than toasters, but not much).
-
- What if you want to do two or more things if() something is TRUE (or
- 'not' TRUE)? This is what those curly brackets are for:
-
- if (learning_SALT) // if learning_SALT is TRUE
- { // do whatever is between {}
- read();
- practice();
- }
-
- or more appropriately:
-
- while (learning_SALT) // while learning_SALT is TRUE
- { // do whatever is between {}
- read();
- practice();
- experiment();
- }
- // once learning_SALT is false, the script continues here
-
- Now for some useful stuff to put between all these brackets. The
- functions listed at the beginning of this document will replace the
- dummy functions I demonstrated with in actual scripts. Don't panic,
- but I want you to take a look in the SALT manual just for a second or
- two. If you don't have the manual printed out, you can pretty well
- forget learning anything useful in SALT, unless you have an incredible
- memory, or are multitasking, etc. and can easily browse the manual on
- disk while viewing your script... While programming any script, it is
- essential to be able to quickly check the syntax (format) and 'return
- values' of functions.
-
- Look up waitfor() (all functions are listed alphabetically) and check
- the 'Summary':
-
- waitfor (str <waitstr>, int <timeout>);
-
-
- The L i b e r a t o r v2.31 SALT.DOC - Page 5
-
-
-
-
- This is not actually how you use the function. You don't type in 'str
- <waitstr>', etc. These items are used as placeholders, to show you
- what is expected, and where it is expected (commas always separate
- arguments). 'str' refers to a 'string' (a bunch of letter, numbers,
- symbols: a sentence) 'int' is an 'integer' (a number without a decimal
- point: 1, -5, 10, 5000, etc). The angle brackets surround <descrip-
- tions>, to give you some idea what the 'str' (string) or 'int'
- (integer) is used for. Above, 'str <waitstr>' would be replaced with
- the string (text) you want to wait for. Strings must be enclosed in
- double quotes:
-
- "This is a string of text that could replace str <waitstr>."
-
- <timeout> would be replaced with the number of seconds you want to wait
- before 'timing out' (giving up).
-
- E.g. waitfor("First name?", 10); // wait 10 seconds for "First name?"
-
- Also, check what waitfor() has to say under 'Return Value'. As you'll
- see, it 'returns' TRUE if the string is found, and FALSE if it isn't
- found... which makes it very convenient to test with an if() or
- while(). Remember, if() and while() test the END RESULT of whatever is
- between their brackets, and if you stick a function such as waitfor()
- there, then the end result is the 'return value' of waitfor(). The
- 'return value' is always the end result of a function. Don't worry
- about how it actually 'returns' this value, or even what a return value
- is. For now, just accept that most functions have return values that
- can be tested with if() or while():
-
- if ( waitfor("First name?", 10) )
- cputs("John Smith^M");
-
- The above may look complex, but it's really not. The outer set of
- brackets go with the if(), the inner go with the waitfor(). '^M' (two
- characters, ^ and M) signifies Ctrl-M which is a Carriage Return or the
- same as hitting <Return> or <Enter>. If any of your 'strings' don't
- get <Enter>ed in your scripts, add ^M to the end of the string, before
- the closing quote (").
-
- Is this too easy? Now, what is stopping you from applying what you
- know about waitfor(), and the SALT manual, to the other SALT functions
- I pointed out at the beginning? Nothing at all... that's the whole
- idea. If you understand the above, and understand what purpose looking
- up a function in the SALT manual serves, then there really isn't much
- more you need to know about SALT. It will only be a matter of time
- until you memorize waitfor()... then cputs()... and so on until you can
- create SALT scripts in your sleep. The only complicated part of
- programming in SALT is trying to keep all the arguments straight (does
- int <timeout> come first, or str <waitstr> in waitfor()... etc). This
- is why I said it will be almost impossible to get anywhere in SALT
- without instant access to the SALT manual. After over a year of
- constant SALT programming, I still refer to the SALT manual frequently,
-
-
- The L i b e r a t o r v2.31 SALT.DOC - Page 6
-
-
-
- just to check what goes where, and what is returned.
-
- EXAMPLES:
-
- Many useful tasks can be carried out by simply waitingfor() a question
- or message, and cputs()ing the reply or carrying out some other
- function, such as receive()ing files, or opening a capture() file, etc.
- You needn't use the track()/track_hit() functions, demonstrated in the
- logon scripts, unless you absolutely have to track more than one prompt
- at once.
-
- Here's an example how to use waitfor() effectively:
-
- main()
- {
- if (not waitfor("First name?", 10))
- goto ERROR;
- cputs("Your Name^M");
-
- // this type of thing can handle many tasks. It means: 'if
- // "First name?" DOESN'T come in within 10 seconds, jump down
- // to the label ERROR below. Otherwise put the string "Your
- // Name^M" out the comm. port' (send it to the BBS). Remember, 'not'
- // means 'not TRUE' (FALSE), which is what waitfor() returns if
- // <waitstr> is not found.
-
- // ... Continue on here with the same type of thing for the next
- // question or operation... You can handle just about anything
- // with something like the above. Replace the cputs() with what-
- // ever you want to do.
-
- // ...
-
- if (waitfor("Command?", 10)) // logon complete?
- return; // end the script here to avoid ERROR:
-
- ERROR: // labels used by 'goto's end with
- // a colon (:)
- hangup(); // hangup() the modem
- }
-
- I created the script below for use on a local BBS, using a few of the
- functions outlined at the beginning. The script OPENs Mark Herring's
- update door, hits a key at the end of each page while() the news is
- being displayed, then selects and downloads my new copy of Deluxe (note
- that you must be a registered Deluxe user to take advantage of the
- update door, so please don't ask your Sysop for access if you are not a
- registered Deluxe user). Once compiled, I put the scripts' name in
- Custom Command 1 of a Liberator Command File (e.g. @SPUD-DL), and have
- the whole process carried out automatically--The Liberator does the
- dialing/logon/logoff, and SPUD-DL handles the download:
-
-
-
-
- The L i b e r a t o r v2.31 SALT.DOC - Page 7
-
-
-
- ///////////////////////// SPUD-DL.SLT ///////////////////////////////
- main()
- {
- cputs("OPEN 48^M"); // open door 48; replace w/proper door# for
- // your BBS
- // translation: put the string "OPEN 48<Enter>" out the comm.
- // port (same as typing it manually online). Note the double quotes
- // around OPEN 48^M, which must always surround strings.
-
- if (not waitfor("Deluxe Update Door", 120))
- return(0);
-
- // translation: wait 120 seconds for the string "Deluxe
- // Update Door" to come in from the BBS. If it doesn't come in,
- // return() a 0 to 'the caller' (if called from a Custom Command,
- // 'the caller' is The Liberator). You can break it down to
- // three SALT functions: if(), waitfor(), and return(). A
- // return() from main() always ends the script at that point.
-
- while (waitfor("Press any key to continue...", 8))
- cputs("^M");
-
- // translation: wait 8 seconds for the string "Press any key to
- // continue..." to come in, and 'while' the string keeps coming
- // in, put an <Enter> (^M) out the communications port. This
- // can also be broken down to three functions: while(),
- // waitfor(), cputs(). When 8 seconds go by without receiving
- // the string, waitfor() will return FALSE (zero), thus ending the
- // while() loop and continuing below.
-
- cputs("ALL^M"); // select ALL files for downloading (Door option)
- delay_scr(20); // delay for 20/10th's of a second, or 2 seconds
- cputs("DOWNLOAD^M"); // send the door command to start the download
-
- if (waitfor("Begin your Zmodem download now...", 200))
- receive('Z', "");
-
- // if the prompt "Begin your Zmodem download now..." comes in
- // within 200 seconds, then we start the download with the
- // receive(). Otherwise we ignore the receive and continue
- // below. See the SALT manual for send/receive protocol
- // letters. Also note that the Zmodem protocol passes the
- // filename (the BBS sends it with the file), so we don't have
- // to specify it in the receive() function--hence the "" where
- // the filename should be. Receive() continues below when the
- // download completes...
-
- waitfor("Command? ", 10); // pause for 10 seconds or until prompt
- cputs("QUIT^M"); // then exit the door and...
- waitfor("Command? ", 120);// waitfor PCBoard prompt to let The
- // Liberator continue.
- }
- /////////////////////////////////////////////////////////////////
-
-
- The L i b e r a t o r v2.31 SALT.DOC - Page 8
-
-
-
-
- The script above is included with The Liberator, so you needn't type it
- in if you have an update door on your BBS and want to make use of it.
- Of course, you should change the door number in the "OPEN 48" to the
- correct door on your BBS. Simply type OPEN manually at a PCBoard
- prompt to view available doors and see if your BBS has a Deluxe update
- door. You must have registered Mark Herring's Shareware reader, and
- have a Deluxe serial number before making use of the door. If the door
- doesn't let you in, leave a C)omment to your Sysop with your Deluxe
- serial number.
-
- I called the script SPUD-DL.SLT, for SParky (Mark Herring's nickname)
- Update Door-DownLoad script. All scripts, as I'm sure you are aware,
- must be compiled before use with the 'CS.EXE' (Compile Script) program.
- Type 'CS SPUD-DL' to compile this one.
-
- You can use the above techniques to automate just about any job
- (waitfor a prompt, if not found 'goto' somewhere else, or 'return',
- otherwise enter the response). I hope that if you are confused by any
- of the above, that you'll take the time to review it and experiment
- with some of the functions listed. Learning the above basics of SALT
- will give you considerably more enjoyment from Telix.
-
- Another Telix automator allows you to create scripts using something
- like the above limited functions, but implements it so that the scripts
- can only be interpreted by the automator itself and are useless to
- Telix. The syntax of the functions is different (dropping a bracket
- here, adding a colon there), but just as time-consuming as learning the
- actual SALT functions, in my opinion. I think you're better off
- spending your time gaining some control over SALT itself, so that you
- are not dependant on The Liberator to run your scripts for you. This
- gives you the chance to automate tasks on BBS's that The Liberator
- doesn't support, plus gives you more use of Telix itelf.
-
- For PCBoard BBS scripts though, you might as well plug the scripts you
- create into a Custom Command and take advantage of The Liberator's
- logon/logoff, dialing delay, Master, etc. Having The Liberator execute
- other SALT scripts is very simple. See the section on Custom Commands
- in LIBERATE.DOC for more information.
-
- If you absolutely have to waitfor() more than one prompt at one time,
- you must use the track()/track_hit() functions, which are demonstrated
- in PCBOARD.SLT and other logon scripts. However, if possible start
- with only the functions pointed out above, to avoid getting over-
- whelmed. There are quite a few functions in SALT, and I still keep the
- manual within arm's length to look up functions I don't use very
- often. You truly won't get anywhere in SALT, without using the SALT
- manual, unless you can somehow memorize the syntax/return values for
- every function you use. Keep the manual handy for reference, now that
- you know how to use it. Look up functions for reference when you need
- them.
-
- One thing I'd also like to demonstrate, is how to define your own
-
-
- The L i b e r a t o r v2.31 SALT.DOC - Page 9
-
-
-
- 'functions' in SALT. It is almost so easy that it's not worth
- explaining, since all you have to do is think up a name, and stick the
- function in your script, just as you create the main() function. The
- reason I want to demonstrate functions is to save you the inevitable
- frustration of forgetting to put a ^M after your string, within
- cputs(). To avoid having to specify ^M for each string, we simply
- create a new cputs() function:
-
- ///////////////////// Start of script ///////////////////////////
- main()
- {
- cputs_cr("Will <Enter> be sent after this string?");
- }
-
- cputs_cr(str string)
- {
- cputs(string);
- cputs("^M"); // Yes, cputs_cr() never forgets the ^M...
- }
- ////////////////////// End of script ////////////////////////////
-
- The above is one script consisting of two separate functions: main()
- and cputs_cr() (cputs with a CR or carriage return). You could call
- cputs_cr() 'knurts()' if you wanted to... but normally we try to make
- the name remind what the function does. Cputs_cr() accepts 1 str
- (string) and chooses to call it 'string'. You could also call 'string'
- anything you wanted to:
-
- cputs_cr(str salt_is_easy)
- {
- cputs(salt_is_easy);
- cputs("^M");
- }
-
- Once you stick cputs_cr() in any of your Telix scripts, you can then
- use it just as you would cputs! If you wanted to pause the entry of
- 'string' for certain time before cputs()ing it, you could also pass a
- delay to cputs_cr() like so:
-
- main()
- {
- cputs_cr("This is a string", 5);
- }
- cputs_cr(str string, int delay_time)
- {
- delay_scr(delay_time); // delay_scr() pauses the script
- cputs(string);
- cputs("^M");
- }
-
- Using functions() can really cut down on your typing, and can make
- scripts much easier to work with -- and more reliable.
-
-
-
- The L i b e r a t o r v2.31 SALT.DOC - Page 10
-
-
-
- Before coming to a close, there's also one other item, that while it
- wasn't used in any of the scripts demonstrated here, it is used in the
- logon scripts provided with Telix and can be fairly confusing to
- beginners. What I'm referring to the equality test ==, or two equals
- signs. Why use two instead of just one? Well, in SALT one equal sign
- is used to actually ASSIGN a value to a specific item. If you wanted
- to set the 'variable' stat to the number 10, you would use:
-
- stat = 10;
-
- To *test* whether stat was EQUAL TO the number 10, you use two equals
- signs:
-
- if (stat == 10)
- prints("This is printed if stat is equal to 10");
-
- If you used 'if (stat = 10)' then Telix would actually ASSIGN 10 to the
- variable stat, then of course the if() would be TRUE since 10 is a TRUE
- value (non zero). This is one to watch for in your scripts. Telix
- doesn't give a warning if you use the wrong number of equals signs,
- since you may have a good reason for one or two in any situation... it
- assumes you know what you're doing. If something is getting carried
- out when it shouldn't, first check for a semicolon following the if();
- or while(); and if that's not the problem see if you inadvertanly used
- the assigment operator (=) instead of the equality test (==).
-
- That's it for now. I know you probably still have many questions, and
- I hope to expand this tutor in the future... but I hope it was
- informative and allows you to make some use of Telix SALT!
-
-